package com.ucode.hrm.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.ucode.hrm.controller.service.ApiHrmDataPermissionService;
import com.ucode.hrm.service.*;
import com.ucode.model.hrm.*;
import com.ucode.model.hrm.convert.HrmEmployeeContractConvert;
import com.ucode.model.hrm.enums.HrmEmployeeContractTypeEnum;
import com.ucode.model.hrm.enums.HrmEmploymentTypeEnum;
import com.ucode.model.hrm.enums.HrmSysResultCodeEnum;
import com.ucode.model.hrm.form.HrmEmployeeContractCreateForm;
import com.ucode.model.hrm.form.HrmEmployeeContractRenewForm;
import com.ucode.model.hrm.vo.HrmEmployeeContractVO;
import com.ucode.tool.annotation.DataPermission;
import com.ucode.tool.base.Paginator;
import com.ucode.tool.base.ResponseResult;
import com.ucode.tool.base.enums.GlobalResultCodeEnum;
import com.ucode.tool.exception.UcodeServiceException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.*;

@Tag(name = "管理后台 - 人力资源系统 - 员工合同")
@RestController
@RequestMapping("/hrm/employee-contract")
@Validated
public class HrmEmployeeContractController {

    @Resource
    private HrmEmployeeContractService employeeContractService;
    @Resource
    private HrmCustomerProjectService customerProjectService;
    @Resource
    private HrmCustomerCompanyService  customerCompanyService;
    @Resource
    private HrmEmployeeService employeeService;
    @Resource
    private HrmEmployeeCompensationService employeeCompensationService;
    @Resource
    private HrmCompanyService companyService;
    @Resource
    private HrmContractTplService contractTplService;
    @Resource
    private ApiHrmDataPermissionService apiHrmDataPermissionService ;

    @GetMapping("/page-list")
    @Operation(summary = "获得分页列表")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-contract:query')")
    @DataPermission(permissions={"hrm:employee-contract:query"})
    public ResponseResult<Paginator<HrmEmployeeContractVO>> pageList(
            @Schema(description = "合同编号") @RequestParam(value = "contractId",required = false) String contractId,
            @Schema(description = "客户公司编码") @RequestParam(value = "customerCompanyId",required = false) Long customerCompanyId,
            @Schema(description = "员工姓名") @RequestParam(value = "employeeName",required = false) String employeeName,
            @Schema(description = "手机号") @RequestParam(value = "employeeMobile",required = false) String employeeMobile,
            @Schema(description = "合同类型") @RequestParam(value = "contractType",required = false) Integer contractType,
            @Schema(description = "合同状态") @RequestParam(value = "status",required = false) Integer status,
            @Schema(description = "创建时间区间",example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")  @RequestParam(value = "createTimeInterval",required = false) LocalDateTime[] createTimeInterval,
            @Schema(description = "页码",example="1") @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @Schema(description = "每页记录数",example="5") @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize){

        Map<String,Object> condition = new HashMap<>();

        if(StrUtil.isNotBlank(contractId) && StrUtil.isNumeric(contractId))
            condition.put("id", contractId);
        if(StrUtil.isNotBlank(employeeName))
            condition.put("employeeName", StrUtil.concat(true,"%", employeeName,"%"));
        if(StrUtil.isNotBlank(employeeMobile))
            condition.put("employeeMobile", StrUtil.concat(true,"%", employeeMobile,"%"));
        if(ArrayUtil.isNotEmpty(createTimeInterval) && createTimeInterval.length == 2){
            condition.put("startTime",createTimeInterval[0]);
            condition.put("endTime",createTimeInterval[1]);
        }
        condition.put("customerCompanyId",customerCompanyId);
        condition.put("contractType",contractType);
        condition.put("status",status);
        condition.put("deltag",false);

        Set<Long> customerProjectIds = apiHrmDataPermissionService.getCurrentUserCustomerProjectIdsByDataPermission();
        //没有可查看的数据
        if(ObjUtil.isNotNull(customerProjectIds) && customerProjectIds.size() == 0){
            return ResponseResult.success(new Paginator<>());
        }
        condition.put("projectIds",customerProjectIds);

        return ResponseResult.success(pageList(condition,pageNum,pageSize));
    }

    private Paginator<HrmEmployeeContractVO> pageList(Map<String,Object> condition, int pageNum, int pageSize) {

        Paginator<HrmEmployeeContract> paginator = employeeContractService.queryPageForList(condition,pageSize,pageNum);
        Paginator<HrmEmployeeContractVO> paginatorVO =  HrmEmployeeContractConvert.INSTANCE.convertPage(paginator);

        if(CollUtil.isNotEmpty(paginatorVO.getList())) {
            Set<Long> customerCompanyIds = new HashSet<>();
            Set<Long> customerProjectIds = new HashSet<>();
            Set<Long> signCompanyIdIds = new HashSet<>();
            Set<Long> tplIds = new HashSet<>();


            for(HrmEmployeeContractVO vo : paginatorVO.getList()){
                if(ObjUtil.isNotNull(vo.getCustomerCompanyId()))
                    customerCompanyIds.add(vo.getCustomerCompanyId());

                if(ObjUtil.isNotNull(vo.getCustomerProjectId()))
                    customerProjectIds.add(vo.getCustomerProjectId());

                if(ObjUtil.isNotNull(vo.getSignCompanyId()))
                    signCompanyIdIds.add(vo.getSignCompanyId());

                tplIds.add(vo.getTemplateId());
            }

            Map<Long, HrmCustomerCompany> customerCompanyMap = customerCompanyService.getMap(customerCompanyIds);
            Map<Long, HrmCustomerProject> customerProjectMap = customerProjectService.getMap(customerProjectIds);
            Map<Long, HrmCompany> signCompanyMap = companyService.getMap(signCompanyIdIds);
            Map<Long, HrmContractTpl> tplMap =  contractTplService.getMap(tplIds);

            paginatorVO.getList().forEach(item -> {

                if(ObjUtil.isNotNull(item.getCustomerCompanyId())) {
                    HrmCustomerCompany customerCompany = customerCompanyMap.get(item.getCustomerCompanyId());
                    if(customerCompany != null)
                        item.setCompanyName(customerCompany.getCompanyName());
                }

                if(ObjUtil.isNotNull(item.getCustomerProjectId())){
                    HrmCustomerProject customerProject = customerProjectMap.get(item.getCustomerProjectId());
                    if(customerProject != null)
                        item.setProjectName(customerProject.getProjectName());
                }

                HrmContractTpl contractTpl = tplMap.get(item.getTemplateId());
                if(ObjUtil.isNotNull(contractTpl)){
                    item.setTplName(contractTpl.getTplName());
                }
            });
        }

        return paginatorVO;
    }

    @GetMapping("/getById/{id}")
    @Parameter(description="主键ID",name = "id", required = true,in = ParameterIn.PATH,example = "1024")
    @Operation(summary = "主键获得信息")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-contract:query')")
    public ResponseResult<HrmEmployeeContractVO> getById(@PathVariable(name="id",required=true) Long id){

        HrmEmployeeContract bean =employeeContractService.validate(id);
        HrmEmployeeContractVO  vo = HrmEmployeeContractConvert.INSTANCE.convert(bean);


        if(ObjUtil.isNotNull(vo.getCustomerCompanyId())) {
            HrmCustomerCompany customerCompany = customerCompanyService.selectByPrimaryKey(bean.getCustomerCompanyId());
            if(customerCompany != null)
                vo.setCompanyName(customerCompany.getCompanyName());
        }

        if(ObjUtil.isNotNull(vo.getCustomerProjectId())){
            HrmCustomerProject customerProject = customerProjectService.selectByPrimaryKey(vo.getCustomerProjectId());
            if(customerProject != null)
                vo.setProjectName(customerProject.getProjectName());
        }

        HrmContractTpl contractTpl = contractTplService.selectByPrimaryKey(vo.getTemplateId());
        if(ObjUtil.isNotNull(contractTpl)){
            vo.setTplName(contractTpl.getTplName());
        }

        return ResponseResult.success(vo);
    }

    @PostMapping("/create")
    @Operation(summary = "创建")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-contract:create')")
    public ResponseResult<Long> create(@Valid @RequestBody HrmEmployeeContractCreateForm form) {
        List<HrmEmployee> employeeList =employeeService.selectByPrimaryKeys(form.getEmployeeIds());
        if(CollUtil.isNotEmpty(employeeList)) {
            Map<Long, HrmEmployeeCompensation> employeeCompensationMap = employeeCompensationService.getMap(form.getEmployeeIds());
            HrmCompany company = companyService.validate(form.getSignCompanyId());
            HrmContractTpl contractTpl = contractTplService.validate(form.getContractTplId());

            for(HrmEmployee employee : employeeList){
                HrmEmployeeCompensation compensation = employeeCompensationMap.get(employee.getId());

                if(ObjUtil.isNull(compensation)){
                    throw new UcodeServiceException(HrmSysResultCodeEnum.EMPLOYEE_COMPENSATION_NOT_EXISTS);
                }

                if(ObjUtil.equals(employee.getEmploymentType(), HrmEmploymentTypeEnum.LEFT.getCode())){
                    continue;
                }

                HrmEmployeeContract employeeContract = HrmEmployeeContractConvert.INSTANCE.build(employee,compensation,company,contractTpl);

                if(ObjUtil.equals(form.getContractType(),2)){
                    if(ObjUtil.isNull(employee.getContractEndDate())){
                        throw new UcodeServiceException(GlobalResultCodeEnum.VALIDATE_FAILED.getCode(),"员工续签合同时，员工信息中合同到期时间不能为空，请检查");
                    }
                    if(employee.getContractEndDate().isAfter(form.getEndDate())){
                        throw new UcodeServiceException(HrmSysResultCodeEnum.CONTRACT_END_TIME_ERROR);
                    }
                    employeeContract.setStartDate(employee.getContractEndDate().plusDays(1));
                    employeeContract.setEndDate(form.getEndDate());
                    employeeContract.setContractType(HrmEmployeeContractTypeEnum.CONTINUE.getCode());
                }else if(ObjUtil.equals(form.getContractType(),3)){
                    employeeContract.setEndDate(form.getEndDate());
                    employeeContract.setContractType(HrmEmployeeContractTypeEnum.DIMISSION.getCode());
                }

                employeeContractService.insert(employeeContract);
            }

        }
        return ResponseResult.success() ;
    }

    @PostMapping("/renew")
    @Operation(summary = "合同续签")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-contract:renew')")
    public ResponseResult<Object> update(@Valid @RequestBody HrmEmployeeContractRenewForm form) {

        HrmEmployeeContract employeeContract = employeeContractService.validate(form.getContractId());
        //验证时间
        if(!form.getEndDate().isAfter(employeeContract.getEndDate())){
            throw new UcodeServiceException(GlobalResultCodeEnum.VALIDATE_FAILED);
        }

        HrmEmployee employee = employeeService.validate(employeeContract.getEmployeeId());
        HrmEmployeeCompensation compensation = employeeCompensationService.validate(employee.getId());
        HrmCompany company = companyService.validate(form.getSignCompanyId());
        HrmContractTpl contractTpl = contractTplService.validate(form.getContractTplId());

        HrmEmployeeContract renewContract = HrmEmployeeContractConvert.INSTANCE.buildRenew(employee,compensation,employeeContract,company,contractTpl,form);
        employeeContractService.insert(renewContract);
        return ResponseResult.success() ;
    }

    @PostMapping("/logic-delete/{id}")
    @Operation(summary = "转移到回收站")
    @Parameter(description="主键ID",name = "id", required = true,in = ParameterIn.PATH, example = "1024")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-contract:logic-delete')")
    public ResponseResult<Object> logicDelete(@PathVariable(name="id",required=true) Long id) {
        //逻辑删除
        int i = employeeContractService.logicDeletePrimaryKey(id);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

    @PostMapping("/batch-logic-delete")
    @Operation(summary = "批量转移到回收站")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-contract:logic-delete')")
    public ResponseResult<Boolean> batchLogicDeletePrimaryKey(@Schema(description = "编号集合",requiredMode = Schema.RequiredMode.REQUIRED)
                                                @NotEmpty(message = "编号集合为空")@Size(min = 1,max = 100,message = "编号集合数量为1-100条")
                                                @RequestParam(value = "ids",required = true) List<Long> ids) {
        int i = employeeContractService.logicDeleteByPrimaryKeys(ids);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

    @PostMapping("/batch-update-visible")
    @Operation(summary = "批量更新可见状态")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-contract:update-visible')")
    public ResponseResult<Boolean> batchUpdateVisible(@Schema(description = "编号集合",requiredMode = Schema.RequiredMode.REQUIRED)
                                                              @NotEmpty(message = "编号集合为空")@Size(min = 1,max = 100,message = "编号集合数量为1-100条")
                                                              @RequestParam(value = "ids",required = true) List<Long> ids,
                                                      @Schema(description = "编号集合",requiredMode = Schema.RequiredMode.REQUIRED)
                                                      @RequestParam(value = "visible",required = true) Boolean visible
                                                      ) {
        int i = employeeContractService.updateVisibleByIds(ids, visible);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }
}
